#include "Game.h"

CGame::CGame():IDLoading(0),KeyPressedTimer(0),CheatEnabled(true)
{
}

CGame::~CGame()
{
}

s32 CGame::EnterState()
{
    switch (StateID)
    {
        case STATE_SUPERYOOP_GAME_SET_POSITIONS:
        {
            board.SetFichaOnTop(&Ficha);
        }
        break;

        case STATE_SUPERYOOP_GAME_START_GAME:
        {
       		TimerFichaMovement = TimeManager->GetNewTimer();
			TimerShootFicha = TimeManager->GetNewTimer();
			TimerPauseGame = TimeManager->GetNewTimer();

            em.Start(TIME_FICHA_START);
        }
        break;

        case STATE_SUPERYOOP_GAME_DESTROY_GAME:
        {
        	Ficha.GetFichaGraph()->Destroy();
			em.Destroy();
			board.Destroy();

			TimeManager->DeleteTimer(TimerFichaMovement);
			TimeManager->DeleteTimer(TimerShootFicha);
			TimeManager->DeleteTimer(TimerPauseGame);

			StateManager->ChangeState(this,STATE_SUPERYOOP_GAME_EXIT_GAME);
        }
        break;

        case STATE_SUPERYOOP_GAME_EXIT_GAME:
        {
			StateManager->SetFinish(this);
        }
        break;
    }

	return 0;
}

s32 CGame::ExitState()
{
	return 0;
}

s32 CGame::Update()
{
    switch (StateID)
    {
        case STATE_SUPERYOOP_GAME_LOADGAME:
        {
            if (IDLoading==0)
            {
                STextureCreationParams tcp;
                tcp.UseTransparentColor = true;
                tcp.TransparentColor.r = 1.0;
                tcp.TransparentColor.b = 1.0;
                TextureManager->SetTextureCreationParams(&tcp);
                ConfigManager->SetActualSection("SuperYoop");
                ConfigManager->ReadFile("SuperYoop.cfg");
            }
            else if (IDLoading==1)
            {
                // Read the board size from the configuration file.
                ActualLevel = "Level0";
                board.SetLevel(ActualLevel);
                board.SetBoardSize();

            }
            else if (IDLoading==2)
            {
                // Load the ficha.
                Ficha.GetFichaGraph()->LoadNode("ficha.gff");
                Ficha.GetFichaGraph()->GetSpriteNode()->SetPosition(0,0,FICHA_Z_POS);
                board.SetSizeBoardCell(Ficha.GetFichaGraph());
                Ficha.ChangeIDColor(0);

                board.LoadBoard();

                em.Load(ActualLevel);
            }
            else if (IDLoading==3)
            {
//				sm.InitGraphs();
            }
            else
            {
                SceneManager->Sort();
                StateManager->ChangeState(this,STATE_SUPERYOOP_GAME_SET_POSITIONS);
            }

            IDLoading++;

        }
        break;

        case STATE_SUPERYOOP_GAME_SET_POSITIONS:
        {
                StateManager->ChangeState(this,STATE_SUPERYOOP_GAME_START_GAME);
        }
        break;

        case STATE_SUPERYOOP_GAME_START_GAME:
        {
        	TimeManager->SetAndStartTimer(TimerFichaMovement,0);
        	TimeManager->SetAndStartTimer(TimerShootFicha,0);
			TimeManager->SetAndStartTimer(TimerPauseGame,0);
            StateManager->ChangeState(this,STATE_SUPERYOOP_GAME_PLAYING_GAME);
        }
        break;

        case STATE_SUPERYOOP_GAME_PLAYING_GAME:
        {
			MoveFicha(KEY_X,true,false);
			MoveFicha(KEY_W,true,true);
			MoveFicha(KEY_A,false,true);
			MoveFicha(KEY_D,false,false);

            ShootFicha(KEY_SPACE);

           if (em.Update(&board))
           {
				// Game over trigered.
//				pLogDebug << "Game over!" << endl;
//				StateManager->ChangeState(this,STATE_SUPERYOOP_GAME_GAME_OVER);
           }

           if (InputManager->GetKeyState(KEY_ESCAPE)->PressedDown)
           {
                PauseGame(KEY_P,true);
                StateManager->ChangeState(this,STATE_SUPERYOOP_GAME_DESTROY_GAME);
           }

           if (CheatEnabled)
           {
				if (InputManager->GetKeyState(KEY_SUBTRACT)->Pushed)
				{
					em.IncEnemySpeed(100);
				}
				else if (InputManager->GetKeyState(KEY_ADD)->Pushed)
				{
					em.IncEnemySpeed(-100);
				}
           }
        }
        break;

        case STATE_SUPERYOOP_GAME_PAUSE_GAME:
        {
            u32 Time = TimeManager->GetActualTime();

            if (Time - KeyPressedTimer > FICHA_MOVEMENT_TIME)
            {
                PauseGame(KEY_P,false);
            }
        }
        break;
    }

	return 0;
}

bool CGame::PauseGame(u8 Key,bool Pause)
{
    if (InputManager->GetKeyState(Key)->PressedDown)
    {
        if (Pause)
        {
            StateManager->ChangeState(this,STATE_SUPERYOOP_GAME_PAUSE_GAME);
            pLogDebug << "Game paused" << endl;
        }
        else
        {
            StateManager->ChangeState(this,STATE_SUPERYOOP_GAME_PLAYING_GAME);
            pLogDebug << "Game unpaused" << endl;
        }

        return true;
    }

    return false;
}

void CGame::ShootFicha(u8 Key)
{
	if (TimerShootFicha->IsEnded() && TimerFichaMovement->IsEnded())
	{
		if (InputManager->GetKeyState(Key)->PressedDown)
		{
			vector2du32 Last;
			em.DestroyEnemiesForFicha(&Ficha,&board,&Last);
			FichaDoDestroyEnemiesAnimation(Last);

			TimeManager->SetAndStartTimer(TimerShootFicha,FICHA_DELETE_ENEMIES_TIME);
		}

	}
}

void CGame::FichaDoDestroyEnemiesAnimation(vector2du32 &ToWhere)
{
	vector2du32 ActualPos = Ficha.GetPos();

	SceneManager->AddMoveAnimator(Ficha.GetFichaGraph()->GetSpriteNode(),
	vector3dvpos(board.GetBoardXPosition(Ficha.GetPosX()),board.GetBoardYPosition(Ficha.GetPosY()),FICHA_Z_POS),
	vector3dvpos(board.GetBoardXPosition(ToWhere.X),board.GetBoardYPosition(ToWhere.Y),FICHA_Z_POS),
	FICHA_DELETE_ENEMIES_TIME / 2);

	SceneManager->AddMoveAnimator(Ficha.GetFichaGraph()->GetSpriteNode(),
	vector3dvpos(board.GetBoardXPosition(ToWhere.X),board.GetBoardYPosition(ToWhere.Y),FICHA_Z_POS),
	vector3dvpos(board.GetBoardXPosition(Ficha.GetPosX()),board.GetBoardYPosition(Ficha.GetPosY()),FICHA_Z_POS),
	FICHA_DELETE_ENEMIES_TIME / 2);
}

void CGame::MoveFicha(u8 Key,bool Vertical,bool Minus)
{
	if (TimerFichaMovement->IsEnded() && TimerShootFicha->IsEnded())
	{
		if (InputManager->GetKeyState(Key)->PressedDown)
		{
			u32 actual = (Vertical?Ficha.GetPosY():Ficha.GetPosX());
			u32 var=0;
			bool result;
			u32 max;
			s32 incx;
			s32 incy;

			if (Vertical)
			{
				incx = 0;
				incy = 1;
				if (Minus)
					var = board.GetMoveQuad().Top.Y;
				else
					var = board.GetMoveQuad().Down.Y;
			}
			else
			{
				incx = 1;
				incy = 0;

				if (Minus)
					var = board.GetMoveQuad().Top.X;
				else
					var = board.GetMoveQuad().Down.X;
			}

			max = var;

			if (Minus)
			{
				result =  (actual - 1 >= (u32)max);
				incx *= -1;
				incy *= -1;
			}
			else
			{
				result = (actual + 1 <= (u32)max);
			}

			if (result)
			{
				SceneManager->AddMoveAnimator(Ficha.GetFichaGraph()->GetSpriteNode(),
				vector3dvpos(board.GetBoardXPosition(Ficha.GetPosX()),board.GetBoardYPosition(Ficha.GetPosY()),FICHA_Z_POS),
				vector3dvpos(board.GetBoardXPosition(Ficha.GetPosX() + incx),board.GetBoardYPosition(Ficha.GetPosY() + incy),FICHA_Z_POS),
				FICHA_MOVEMENT_TIME - 10);

				Ficha.SetFichaPos(Ficha.GetPosX() + incx,Ficha.GetPosY() + incy);
			}

			if (incx > 0)
				Ficha.SetFichaHeading(FICHA_HEADING_RIGHT);
			else if (incx < 0)
				Ficha.SetFichaHeading(FICHA_HEADING_LEFT);
			else if (incy > 0)
				Ficha.SetFichaHeading(FICHA_HEADING_DOWN);
			else if (incy < 0)
				Ficha.SetFichaHeading(FICHA_HEADING_UP);

			TimeManager->SetAndStartTimer(TimerFichaMovement,FICHA_MOVEMENT_TIME);
		}
	}
}
